#include <iostream>
#include <unistd.h>
#include <vector>
#include <pthread.h>
#include "pthread.hpp"
#include "Ring_Queue.hpp"
#include "Ring_Queue.hpp"
#include "Task.hpp"
using namespace pthread_moudle;

using ring_queue_t = RingQueue<Task>;
int g_val = 10;
void ProductorTask(ring_queue_t &rq)
{
    srand(time(nullptr));
    while (true)
    {
        sleep(1);
        int a = rand() % 100, b = rand() % 100;
        Task t(a, b);
        std::cout << "productor---push task data a: " << a << ",b: " << b << std::endl;
        rq.Enqueue(t);
    }
}

void ConsumerTask(ring_queue_t &rq)
{
    while (true)
    {

        sleep(1);
        Task out;
        rq.Pop(&out);
        std::cout << "consumer---get result:  " << out.excute() << std::endl;
    }
}

// 初始化
void InitCommand(std::vector<Thread<ring_queue_t>> *Threads, int Thread_num, ring_queue_t &rq, pthread_moudle::func_t<ring_queue_t> func, std::string who)
{
    for (int i = 0; i < Thread_num; i++)
    {
        std::string name = "Thread---" + std::to_string(i + 1) + who;
        Threads->emplace_back(func, rq, name); // 直接构造对象入vector数组
    }
}
// 初始化生产者
void InitProductor(std::vector<Thread<ring_queue_t>> *Threads, int Thread_num, ring_queue_t &rq)
{
    InitCommand(Threads, Thread_num, rq, ProductorTask, "--[productor]");
}
// 初始化消费者
void InitConsumer(std::vector<Thread<ring_queue_t>> *Threads, int Thread_num, ring_queue_t &rq)
{
    InitCommand(Threads, Thread_num, rq, ConsumerTask, "--[consumer]");
}

void StartAllThreads(std::vector<Thread<ring_queue_t>> &Threads)
{
    for (auto &thread : Threads)
    {
        thread.start();
    }
}

// 等待所有线程
void WaitAllPthread(std::vector<Thread<ring_queue_t>> &Threads)
{
    for (auto &Thread : Threads)
    {
        Thread.join();
    }
}
int main()
{
    ring_queue_t *rq = new ring_queue_t(5);
    std::vector<Thread<ring_queue_t>> Threads;

    // 初始化生产者线程
    InitProductor(&Threads, 2, *rq);

    // 初始化消费者线程
    InitConsumer(&Threads, 3, *rq);

    // 启动所有线程
    StartAllThreads(Threads);

    // 等待所有线程
    WaitAllPthread(Threads);
    return 0;
}